﻿using Max.PH5_2010A.Shopping.Domain;
using Max.PH5_2010A.Shopping.DTO;
using Max.PH5_2010A.Shopping.IRespository;
using Max.PH5_2010A.Shopping.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Max.PH5_2010A.Shopping.Service
{
    public class OrderMasterService : BaseService<OrderMasterModel>, IOrderMasterService
    {
        IOrderDetailRespository _detailRespository;
        IOrderMasterRespository _masterRespository;
        IUnitOfWork _unitOfWork;
        IProductSkuRespository _skuRespository;
        public OrderMasterService(IOrderMasterRespository respository, IUnitOfWork unitOfWork, IOrderDetailRespository detailRespository, IProductSkuRespository skuRespository) : base(respository, unitOfWork)
        {
            _detailRespository = detailRespository;
            _masterRespository = respository;
            _unitOfWork = unitOfWork;
            _skuRespository = skuRespository;
        }

        public Tuple<bool, string> CreateOrder(OrderInputDto dto)
        {
            /*
             * 1、生成订单（就是添加的操作）  订单主表和明细表是关系是：1对多
             *      1）添加订单主表信息
             *      2）添加订单对应的商品信息（即订单明细表）
             * 2、删除购物车（从购物车中删除已下单的商品） 
             * 
             * 3、==============修改库存=============
             * **/

            //同时添加主表和明细表数据，要保持两个表的数据同时正确，这个时候我们需要采用事务
            using (var tran = _unitOfWork.GetDbContext().Database.BeginTransaction())
            {
                try
                {
                    //1、生成订单
                    
                    //插入订单主表
                    var master = new Domain.OrderMasterModel()
                    {
                        MemberID = dto.MemberID, //Guid.NewGuid(), //会员ID，从前台传过来的
                        OrderAccount = dto.OrderAccount, //0, //订单总金额，从前台传过来的
                        OrderCreatedTime = DateTime.Now,
                        OrderState = Domain.Shared.OrderState.WaittingPay,
                        RateAccount = 0,
                        RecivedAddress = dto.RecivedAddress, //"上海蒿某个地方", //收件人地址，从前台传过来的
                        RecivedName = dto.RecivedName, // "梁才根",  //收件人姓名，从前台传过来的
                        RecivedPhone = dto.RecivedPhone //"18016435751", //收件人电话，从前台传过来的
                    };
                    _masterRespository.Insert(master);

                    //插入订单明细表
                    List<Domain.OrderDetailModel> details = new();
                    dto.Details.ForEach(x =>
                    {
                        details.Add(new OrderDetailModel
                        {
                            OrderNo = master.OrderNo,
                            ProductId = x.ProductId, //Guid.NewGuid(), //产品Id ，从前台传过来的
                            ProductName = x.ProductName, //"", //产品名称，从前台传过来的
                            ProductPrice = x.ProductPrice,// 0,//产品价格，从前台传过来的
                            ProducuNumber = x.ProducuNumber,// 1,//产品数量，从前台传过来的
                            State = "0"
                        });
                    });
        
                    details.ForEach(x =>
                    {
                        _detailRespository.Insert(x);

                        //锁定库存
                        var m = _skuRespository.Select().Where(s => s.Id == x.ProductId).FirstOrDefault();
                        if(m != null)
                        {
                            //可用库存减少
                            //锁定库存添加
                            m.ValidStock -= x.ProducuNumber;
                            m.LockStock += x.ProducuNumber;
                        }
                        _skuRespository.Update(m);
                    });

                    




                    int result = _unitOfWork.SaveChanges();

                    //成功保存了订单数据，再删除购物车中商品
                    if (result > 0)
                    {
                        //2、删除商品（从购物车中删除--就是购物车批量删除操作）
                        var _redis = new CSRedis.CSRedisClient("127.0.0.1:6379");
                        var _key = master.MemberID.ToString();
                        if (_redis.Exists(_key))
                        {
                            var _carData = _redis.Get<List<ShoppingCarProductInfoDto>>(_key);

                            if (_carData != null || _carData.Count > 0)
                            {
                                details.ForEach(x =>
                                {
                                    var _m = _carData.Where(p => p.ProductId.Equals(x.ProductId.ToString())).FirstOrDefault();
                                    if (_m != null)
                                    {
                                        _carData.Remove(_m);
                                    }
                                });
                                _redis.Set(_key, _carData);
                            }
                        }
                    }

                    tran.Commit();

                    return Tuple.Create(true, master.OrderNo);
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    return Tuple.Create(false, ex.Message);
                }
            }
        }
    }
}
